package com.ggb.reactive.controller.admin

import com.ggb.reactive.constant.JwtClaimsConstant
import com.ggb.reactive.constant.MessageConstant
import com.ggb.reactive.constant.StatusConstant
import com.ggb.reactive.domain.dto.CategoryDTO
import com.ggb.reactive.domain.dto.CategoryPageQueryDTO
import com.ggb.reactive.domain.entity.Category
import com.ggb.reactive.model.PageResult
import com.ggb.reactive.model.WebResult
import com.ggb.reactive.repository.CategoryRepository
import com.ggb.reactive.service.CategoryService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import lombok.RequiredArgsConstructor
import org.springframework.beans.BeanUtils
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.adapter.DefaultServerWebExchange
import reactor.core.publisher.Mono
import java.time.Instant

@RequestMapping("/admin/category")
@RestController
@RequiredArgsConstructor
@Tag(name = "分类管理")
class CategoryController(
    val categoryRepository: CategoryRepository,
    val categoryService: CategoryService
) {


    /**
     * 新增分类
     */
    @Operation(summary = "新增分类")
    @PostMapping
    fun add(@RequestBody categoryDTO: CategoryDTO, exchange: DefaultServerWebExchange): Mono<WebResult<String>> {
        val userId = (exchange.attributes[JwtClaimsConstant.USER_ID] as Int).toLong()
        val category = Category(
            createTime = Instant.now(),
            updateTime = Instant.now(),
            createUser = userId,
            updateUser = userId,
        )
        BeanUtils.copyProperties(categoryDTO, category)
        category.status = StatusConstant.ENABLE.getStatus()
        return categoryRepository.save(category).flatMap {
            Mono.just(WebResult.success<String>())
        }.onErrorResume {
            println(it)
            Mono.just(WebResult.error(MessageConstant.ACTION_FAIL))
        }
    }

    /**
     * 更新分类
     */
    @Operation(summary = "更新分类")
    @PutMapping
    fun update(@RequestBody categoryDTO: CategoryDTO, exchange: DefaultServerWebExchange): Mono<WebResult<String>> {
        val userId = (exchange.attributes[JwtClaimsConstant.USER_ID] as Int).toLong()
        return categoryRepository.findById(categoryDTO.id!!)
            .flatMap { category ->
                // 然后设置updateTime和updateUser
                category.apply {
                    updateTime = Instant.now()
                    updateUser = userId
                    name = categoryDTO.name
                    sort = categoryDTO.sort
                }
                // 保存更新后的实体
                categoryRepository.save(category)
            }
            .map {
                // 在保存操作完成后返回成功的结果
                WebResult.success<String>()
            }
            .onErrorResume {
                // 错误处理
                Mono.just(WebResult.error(MessageConstant.ACTION_FAIL))
            }
    }

    /**
     * 分页查询
     */
    @Operation(summary = "分类分页查询")
    @GetMapping("/page")
    fun page(categoryPageQueryDTO: CategoryPageQueryDTO): Mono<WebResult<PageResult<Category>>> =
        categoryService.findCategoriesByCriteria(categoryPageQueryDTO)

    //{
    //   return categoryService.findCategoriesByCriteria(categoryPageQueryDTO)
    //// 假设EmployeePageQueryDTO中有页码和每页大小
    //val pageRequest = PageRequest.of(categoryPageQueryDTO.page - 1, categoryPageQueryDTO.pageSize)
    //
    //return categoryRepository.findCategoriesByOptionalCriteria(
    //    categoryPageQueryDTO.name,
    //    categoryPageQueryDTO.type
    //).collectList().map { categories ->
    //    // 根据分页参数手动实现分页逻辑
    //    val start = pageRequest.offset.toInt()
    //    val end = (start + pageRequest.pageSize).coerceAtMost(categories.size)
    //    val pageContent = if (start <= end) categories.subList(start, end) else listOf()
    //
    //    PageImpl(pageContent, pageRequest, categories.size.toLong())
    //}
    //    .map { page ->
    //        // 将Page<User>转换为你的PageResult<User>（假设你有一个类似的结构）
    //        Result.success(PageResult(total = page.totalElements, records = page.content))
    //    }
    //}

    /**
     * 启用、禁用分类
     */
    @Operation(summary = "启用、禁用分类")
    @PostMapping("/status/{status}")
    fun status(@PathVariable status: Int?, id: Long?, exchange: DefaultServerWebExchange): Mono<WebResult<String>> {
        //val user = User(id=id,status = status)
        //return myUserRepository.save(user)
        if (id == null) return Mono.just(WebResult.error("id名不能为空"))
        if (status == null) return Mono.just(WebResult.error("status不能为空"))
        val userId = (exchange.attributes[JwtClaimsConstant.USER_ID] as Int).toLong()
        return categoryRepository.updateStatusById(id, status, Instant.now(), userId)
            .map {
                WebResult.success<String>()
            }
            .onErrorResume {
                Mono.just(WebResult.error(MessageConstant.ACTION_FAIL))
            }
    }

    /**
     * 根据类型查询分类
     */
    @Operation(summary = "根据类型查询分类")
    @GetMapping("/list")
    fun list(type: Int): Mono<WebResult<List<Category>>> {

        return categoryRepository.findAllByType(type).collectList().map {
            WebResult.success(it)
        }
    }

    /**
     * 删除分类
     */
    @DeleteMapping
    @Operation(summary = "删除分类")
    fun deleteById(id: Long): Mono<WebResult<String>> {

        /**
         * deleteById方法在Reactive Repository中是一个无返回值的操作（Mono<Void>），这意味着它只表示操作的完成状态，而不携带任何数据。
         */
        return categoryRepository.deleteById(id)
            .then(Mono.just(WebResult.success<String>()))
            .onErrorResume {
                Mono.just(WebResult.error(MessageConstant.ACTION_FAIL))
            }
    }

}